package com.ruoyi.web.controller.system;

import java.util.Date;
import java.util.List;

import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.system.domain.WxCheckoutBody;
import com.ruoyi.system.service.ISysDeptService;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.system.domain.WxRecords;
import com.ruoyi.system.service.IWxRecordsService;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.common.core.page.TableDataInfo;

/**
 * 游戏记录Controller
 * 
 * @author ruoyi
 * @date 2025-08-06
 */
@RestController
@RequestMapping("/system/records")
public class WxRecordsController extends BaseController {
    @Autowired
    private IWxRecordsService wxRecordsService;

    @Autowired
    private ISysDeptService deptService;

    /**
     * 查询游戏记录列表
     */
    @PreAuthorize("@ss.hasPermi('system:records:list')")
    @GetMapping("/list")
    public TableDataInfo list(WxRecords wxRecords) {
        startPage();
        LoginUser loginUser = getLoginUser();
        SysUser user = loginUser.getUser();
        wxRecords.setDeptId(user.getDeptId());
        List<WxRecords> list = wxRecordsService.selectWxRecordsList(wxRecords);
        return getDataTable(list);
    }

    /**
     * 导出游戏记录列表
     */
    @PreAuthorize("@ss.hasPermi('system:records:export')")
    @Log(title = "游戏记录", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, WxRecords wxRecords) {
        List<WxRecords> list = wxRecordsService.selectWxRecordsList(wxRecords);
        ExcelUtil<WxRecords> util = new ExcelUtil<WxRecords>(WxRecords.class);
        util.exportExcel(response, list, "游戏记录数据");
    }

    /**
     * 获取游戏记录详细信息
     */
    @PreAuthorize("@ss.hasPermi('system:records:query')")
    @GetMapping(value = "/{id}")
    public AjaxResult getInfo(@PathVariable("id") Long id) {
        return success(wxRecordsService.selectWxRecordsById(id));
    }

    /**
     * 新增游戏记录
     */
    @PreAuthorize("@ss.hasPermi('system:records:add')")
    @Log(title = "游戏记录", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody WxRecords wxRecords) {
        return toAjax(wxRecordsService.insertWxRecords(wxRecords));
    }

    /**
     * 修改游戏记录
     */
    @PreAuthorize("@ss.hasPermi('system:records:edit')")
    @Log(title = "游戏记录", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody WxRecords wxRecords) {
        return toAjax(wxRecordsService.updateWxRecords(wxRecords));
    }

    /**
     * 删除游戏记录
     */
    @PreAuthorize("@ss.hasPermi('system:records:remove')")
    @Log(title = "游戏记录", businessType = BusinessType.DELETE)
    @DeleteMapping("/{ids}")
    public AjaxResult remove(@PathVariable Long[] ids) {
        return toAjax(wxRecordsService.deleteWxRecordsByIds(ids));
    }


    /**
     * 结束游戏
     */
    @PreAuthorize("@ss.hasPermi('system:records:edit')")
    @Log(title = "游戏记录", businessType = BusinessType.UPDATE)
    @PostMapping("/end")
    public AjaxResult endGame(@RequestBody WxRecords wxRecords) {
        WxRecords tempRecord = wxRecordsService.selectWxRecordsById(wxRecords.getId());
        tempRecord.setEndTime(new Date());//设置结束游戏时间
        //计算金额
        SysDept dept = deptService.selectDeptById(tempRecord.getDeptId());
        String type = dept.getOfferType();
        double price = 0;
        switch (type) {
            case "1":
                //每天最多收4个小时的价钱
                //单价
                if(tempRecord.getGameType().equals("1")){
                    price = dept.getPs();
                }else if(tempRecord.getGameType().equals("2")){
                    price = dept.getSwitchs();
                }else{
                    price = dept.getBoard();
                }
                double top = price * 4;//当天付款上限
                double todayAmount = getTodayAmount(wxRecords);//当天已游玩金额
                if(todayAmount >= top){
                    tempRecord.setAmount((double) 0);//如果当天游戏已超过最高付款金额，则后续免费
                }else{
                    int amountMinutes = getMinutes(tempRecord.getStartTime(), tempRecord.getEndTime());//本次游玩分钟数

                    int minTime = dept.getMinDuration();//最小计时单位（分钟）
                    int timeCount = 0;
                    //分钟数整合，是舍还是入
                    if(dept.getChargeType().equals("0")){
                        timeCount = amountMinutes / minTime;
                    }else{
                        timeCount = amountMinutes % minTime == 0 ? amountMinutes / minTime : (amountMinutes / minTime) + 1;
                    }
                    price = price * minTime / 60;//按最小时间单位重新定义单价
                    double currentAmount = timeCount * price; //本次正常需要付的钱数

                    if(currentAmount + todayAmount >= top){
                        //如果本次需付款+当天应付或已付总额>上限，则只算上限-当天
                        tempRecord.setAmount(top - todayAmount);
                    }else{
                        //如果本次需付款+当天应付或已付总额<上限，则正常算本次
                        tempRecord.setAmount(currentAmount);
                    }
                }
                break;
            default:
                //默认计费模式，即type为0的情况，无优惠
                //单价
                price = 0;
                if(tempRecord.getGameType().equals("1")){
                    price = dept.getPs();
                }else if(tempRecord.getGameType().equals("2")){
                    price = dept.getSwitchs();
                }else{
                    price = dept.getBoard();
                }
                int minTime = dept.getMinDuration();//最小计时单位（分钟）
                int timeCount = 0;
                int currentMinutes = getMinutes(tempRecord.getStartTime(), tempRecord.getEndTime());//本次游玩分钟数
                //分钟数整合，是舍还是入
                if(dept.getChargeType().equals("0")){
                    timeCount = currentMinutes / minTime;
                }else{
                    timeCount = currentMinutes % minTime == 0 ? currentMinutes / minTime : (currentMinutes / minTime) + 1;
                }
                price = price * minTime / 60;//按最小时间单位重新定义单价
                tempRecord.setAmount(timeCount * price);
                break;
        }
        return toAjax( wxRecordsService.endGame(tempRecord));
    }


    /**
     * 结账
     */
    @PreAuthorize("@ss.hasPermi('system:records:edit')")
    @Log(title = "游戏记录", businessType = BusinessType.UPDATE)
    @PostMapping("/checkout")
    public AjaxResult checkout(@RequestBody WxCheckoutBody body) {
        if(body.getVipId() == 0){
            //只改记录，不扣会员
            return toAjax(wxRecordsService.checkoutWhitoutVip(body));
        }else{
            //既改会员余额，也改游戏记录
            return toAjax(wxRecordsService.checkout(body));
        }
    }

    /**
     * 计算当天已累计的钱数
     */
    public double getTodayAmount(WxRecords record) {
        WxRecords temp = new WxRecords();
        temp.setWxId(record.getWxId());
        temp.setDeptId(record.getDeptId());
        temp.setStartTime(new Date());
        temp.setStatus("1");

        List<WxRecords> list1 = wxRecordsService.selectWxRecordsList(temp);

        //循环计算每条记录，开始时间和结束时间的分钟差，累加到minutes中
        double amount = (double) 0;

        for (WxRecords r : list1) {
            amount += r.getAmount();
        }

        temp.setStatus("2");
        List<WxRecords> list2 = wxRecordsService.selectWxRecordsList(temp);

        for (WxRecords r : list2) {
            amount += r.getAmount();
        }

        return amount;
    }

    /**
     * 分钟数做差
     */
    public int getMinutes(Date start, Date end){
        // 保护性判断
        if (start != null && end != null) {
            long diffMillis = end.getTime() - start.getTime();
            return (int) (diffMillis / (60 * 1000)); // 转为分钟
        }else{
            return 0;
        }
    }
}